<template>
  <el-table
    :data="
      props.tableData.slice(
        (currentPage - 1) * pageSize,
        currentPage * pageSize
      )
    "
    :default-sort="defaultSort"
    @sort-change="sortChange"
    @selection-change="selectChange"
    stripe
  >
    <!-- 选择框 -->
    <el-table-column
      align="center"
      type="selection"
      width="55"
      fixed
    ></el-table-column>
    <!-- 序号 -->
    <el-table-column
      align="center"
      type="index"
      label="序号"
      width="60"
    ></el-table-column>
    <!-- 循环生成数据列 -->
    <template
      v-for="(tableColumnField, key) in props.tableColumnFiledList"
      :key="key"
    >
      <template v-if="tableColumnField.showInTable">
        <template v-if="tableColumnField.jsonFiled">
          <template
            v-for="(children, index) in tableColumnField.jsonFiled"
            :key="index"
          >
            <template v-if="children.showInTable">
              <el-table-column
                :align="children.align || 'center'"
                :prop="tableColumnField.filedName + '.' + children.filedName"
                :label="children.label"
                :width="children.width"
                :min-width="children.minWidth"
                :show-overflow-tooltip="true"
                :formatter="
                  (row, column, cellValue) =>
                    format(row, column, cellValue, children)
                "
                sortable="custom"
                fit
              >
              </el-table-column>
            </template>
          </template>
        </template>
        <template v-else>
          <el-table-column
            :align="tableColumnField.align || 'center'"
            :prop="tableColumnField.filedName"
            :label="tableColumnField.label"
            :width="tableColumnField.width"
            :min-width="tableColumnField.minWidth"
            :show-overflow-tooltip="true"
            :formatter="
              (row, column, cellValue) =>
                format(row, column, cellValue, tableColumnField)
            "
            sortable="custom"
            fit
          >
          </el-table-column>
        </template>
      </template>
    </template>
    <template v-if="props.tableFixedFuncBtnList.funcBtnListVisible">
      <el-table-column
        align="center"
        :label="props.tableFixedFuncBtnList.label"
        :width="props.tableFixedFuncBtnList.width"
        fixed="right"
        fit
      >
        <template #default="scope">
          <template
            v-for="(btn, key) in props.tableFixedFuncBtnList.buttonList"
            :key="key"
          >
            <el-button
              type="text"
              size="small"
              :icon="btn.icon"
              @click.prevent="fixedFuncBtnMethod(scope, btn.name)"
            >
              {{ btn.label }}
            </el-button>
          </template>
        </template>
      </el-table-column>
    </template>
  </el-table>
  <div class="table-suffix-tool">
    <el-pagination
      style="float: right"
      layout="total, sizes, prev, pager, next, jumper"
      :total="props.tableData.length"
      :page-sizes="[10, 20, 50, 100]"
      :default-page-size="pageSize"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    ></el-pagination>
  </div>
</template>

<script lang="ts" setup>
// 基础表仅实现表单的基础功能, 对表单进行简单的封装.

// 字段的固有属性, 通过这些属性实现表格和表单数据渲染.
import TableSortEvent from "@/components/table/base/TableSortEvent";
import Pagination from "@/components/table/base/Pagination";
import { FixedFuncBtn } from "@/models/TableSetting";
import Scope from "@/models/Scope";
import { BaseFormat } from "@/components/form/formItem/FormItemMeta";
import { UnwrapRef } from "vue";
import api from "@/utils";

export interface TableColumnFiled {
  filedName: string; // 表格中该字段的字段名.
  label: string; // 表格中该字段展示的名字.
  width?: number; // 表格中该字段所占的宽度.
  minWidth?: number; // 表格中该字段所占的最小宽度.
  formType?: string; // 表格中该字段的类型
  showInTable?: boolean; // 该字段内容是否需要在表格中渲染显示.
  formatter?: BaseFormat; // 该字段用于字段格式化数据
  align?: string; // 该字段的对齐方式
  jsonFiled?: Array<TableColumnFiled>; // json表单字段
}

// 表格的props.
export interface tableProps {
  tableData?: Array<Record<string, unknown>>; // 表格的数据.
  tableColumnFiledList?: Array<TableColumnFiled>; // 表格字段属性列表.
  selects?: Array<Record<string, unknown>>; // 已勾选的数据项.
  tableFixedFuncBtnList?: FixedFuncBtn; // 右侧扩展按钮
}

const props = withDefaults(defineProps<tableProps>(), {
  tableData: () => {
    return [];
  }, // 表数据
  tableColumnFiledList: () => {
    return [];
  }, // 表字段属性
  selects: () => {
    return [];
  }, // 已勾选的数据项.
  tableFixedFuncBtnList: () => {
    return {
      label: "操作",
      width: 120,
      funcBtnListVisible: false,
      buttonList: [],
    } as FixedFuncBtn;
  }, // 右侧扩展按钮
});

// 抛出的事件.
const emit = defineEmits<{
  (e: "select-change", selects: Array<Record<string, unknown>>): void;
  (e: "sort-change", data: Array<Record<string, unknown>>): void; // 排序的抛出方法, 将排序后的tableData抛出.
  (e: "fixed-func-btn-method", scope: Scope, name: string): void; // 扩展栏按钮功能函数.
}>();

// 勾选项发生变化.
const selectChange = (selects: Array<Record<string, unknown>>) => {
  emit("select-change", selects);
  console.log(selects);
};

// 重要! 传props时不能直接传props中的具体属性.
// 表排序
const { defaultSort, sortChange } = TableSortEvent(props, emit);

// 表格分页
const { pageSize, currentPage, handleSizeChange, handleCurrentChange } =
  Pagination();

const fixedFuncBtnMethod = (scope: Scope, name: string) => {
  emit("fixed-func-btn-method", scope, name);
};
// 表单数据格式化
const format = (
  row: UnwrapRef<never>,
  column: UnwrapRef<Record<string, string>>,
  cellValue: UnwrapRef<string>,
  tableColumnFiled: TableColumnFiled
) => {
  // 默认情况下，日期格式自动转化为 yyyy年MM月dd日 的格式
  if (
    tableColumnFiled.formType === "el-form-picker-date" &&
    tableColumnFiled.formatter === undefined
  ) {
    const regDate = /^\d{4}-\d{2}-\d{2}.\d{2}:\d{2}:\d{2}.*$/;
    const isDate = regDate.test(cellValue);
    if (isDate) {
      const date = new Date(cellValue);
      return api.formatDate(date, "yyyy年MM月dd日hh时mm分");
    }
  }
  if (tableColumnFiled.formatter) {
    // 如果formatter为对象类型，根据formatter对数据进行格式化
    if (tableColumnFiled.formatter.date) {
      // 如果是日期类型的数据格式化处理
      const regDate = /^\d{4}-\d{2}-\d{2}.\d{2}:\d{2}:\d{2}.*$/;
      const isDate = regDate.test(cellValue);
      if (isDate) {
        const date = new Date(cellValue);
        return api.formatDate(date, tableColumnFiled.formatter.date);
      }
      return cellValue;
    } else if (tableColumnFiled.formatter.boolean) {
      // 如果是Boolean类型的数据格式化处理
      let temp;
      tableColumnFiled.formatter.boolean.forEach((boolean) => {
        if (boolean.value == cellValue) {
          temp = boolean.label;
        }
      });
      return temp;
    } else if (tableColumnFiled.formatter.number) {
      // 如果是数值类型的数据格式化处理
      let temp;
      tableColumnFiled.formatter.number.forEach((number) => {
        if (number.value == cellValue) {
          temp = number.label;
        }
      });
      return temp;
    } else if (tableColumnFiled.formatter.string) {
      // 如果是字符类型的数据格式化处理
      let temp;
      tableColumnFiled.formatter.string.forEach((string) => {
        if (string.value == cellValue) {
          temp = string.label;
        }
      });
      return temp;
    }
  }
  return cellValue;
};
</script>

<style lang="less" scoped>
.table-suffix-tool {
  background: #ffffff;
  height: 50px;
  width: 100%;
  padding-top: 10px;
}
</style>
